﻿using DllCallAnalysis45;
using DrawIO45.Draws;
using DrawIO45.Draws.Business;
using DrawIO45.Models.DrawIOs;
using DrawIO45.Models.Logic;
using SDILReader;
using System;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Serialization;

namespace DrawIO45
{
    internal class Program
    {
        static string DllPath = string.Empty;

        static string[] GetFiles(string path, params string[] searchs)
        {
            var list = new List<string>();

            foreach (var item in searchs)
            {
                var tmp = Directory.GetFiles(DllPath, item);
                if (tmp?.Any() == true)
                    list.AddRange(tmp);
            }

            return list.Distinct().ToArray();
        }

        static void Main(string[] args)
        {
            Globals.LoadOpCodes();

            DllPath = @"D:\CompanyProjects\EnterpriseWelfare\src\Beisen.EnterpriseWelfare.ServiceImp\bin\Debug";
            var outputFile = $@"D:\Wow\2024-11-05\AutoDrawIO_{DateTime.Now.ToString("yyyyMMddHHmmss")}.drawio";

            var dllFiles = GetFiles(DllPath, "Beisen.Welfare.*.dll", "Beisen.EnterpriseWelfare.*.dll");

            AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;

            var allClassInfo = dllFiles.SelectMany(n => GetAllLClassInfos(Assembly.LoadFile(n))).ToList();


            var igTypes = new string[]
            {
                "Args",
                "Dto",
                "Model",
                "Helper",
                "Help",
                "Extention",
                "Extension",
                "Exstension",
                "Extensions",
                "Exception",
                "Config",
                //"Provider",
                "Repository",
                "ResultInfo",
                "Result",
                "DomainNameList",
                "PublicTenant",
                "ESBAgentInstance",
                "DbName",
                "Request",
                "Map",
                "Type",
                "FrontDataConverter",
                "Entity",
                "Hander",
                "Handle",
                "Manager",
                "Const",
            };

            allClassInfo = allClassInfo
                .Where(n => n.Source.IsClass || n.Source.IsInterface)
                .Where(n => igTypes.All(m => n.Name.EndsWith(m, StringComparison.OrdinalIgnoreCase) != true))
                .Where(n => n.MethodInfos?.Any() == true || n.Properties?.Any() == true)
                .ToList();

            var draws = new IDrawOnRoot[]
            {
                new DrawItem(new DrawItemOption
                {
                    AllowUseTypes = new AllowUseType[]
                    {
                        AllowUseType.Inteface,
                        AllowUseType.Class,
                    },
                    DrawModel = false,
                }),
                new DrawExtend(new DrawExtendOption
                {
                    //IgnoreInterface = true,
                }),
                new DrawImplementedInterface(new DrawImplementedInterfaceOption
                {
                    IgnoreWhenParentImplementedInterface = true,
                }),
                new DrawDependentClass(new DrawDependentClassOption
                {
                    IgnoreWhereExtend = true,
                    IgnoreEmptyMethodClass = false,
                    AllowUseTypes = new AllowUseType[]
                    {
                        AllowUseType.Inteface,
                        AllowUseType.Class,
                    }
                }),
                //new ClearIsolatedIsland(),
                new ClearNotRefRoot(new ClearNotRefRootArgs
                {
                    Roots = new List<string>
                    {
                        "DossierProvider",
                    },
                }),
            };

            // 画出来映射关系
            var file = DrawHelper.DrawFile(allClassInfo, draws);

            XmlSerializer serializer = new XmlSerializer(typeof(MXFile));

            using (var sw = new StreamWriter(outputFile, false, Encoding.Default))
            {
                serializer.Serialize(sw, file);
            }
        }

        private static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
        {
            AssemblyName assemblyName = new AssemblyName(args.Name);

            var searchNames = new[]
           {
                $"{assemblyName.Name}.dll",
                $"{assemblyName.Name}.exe",
            };

            foreach (var item in searchNames)
            {
                var filePath = Path.Combine(DllPath, item);
                if (File.Exists(filePath) != true)
                    continue;

                return Assembly.LoadFrom(filePath);
            }

            return null;
        }


        static List<LClassInfo> GetAllLClassInfos(Assembly assembly)
        {
            var list = new List<LClassInfo>();

            try
            {
                var types = assembly.GetTypes();

                foreach (var type in types)
                {
                    if (type.IsVisible != true)
                        continue;

                    list.Add(LClassInfo.GetClassInfo(type));
                }
            }
            catch (Exception ex)
            {

            }

            return list;
        }
    }
}
